package com.example.index.chat;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;

@Component
@ServerEndpoint(value = "/ws/{userId}")
public class ChatServer {

    private static Map<String, Session> routeTab = new HashMap<>();
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static Set<String> userIdTemp = new HashSet<>();

    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) throws IOException {
        System.out.println(userId);
        routeTab.put(userId, session);
        if (!userIdTemp.contains(userId)) {
            infoToTeacher(MessageType.JOIN);
        }
    }

    //给所有老师发送学生离开或连接信息
    private void infoToTeacher(MessageType messageType) throws IOException {
        System.out.println("给老师广播消息" + messageType);
        for (String key : routeTab.keySet()) {
            if (key.contains("老师")) {
                Session s = routeTab.get(key);
                if (s != null && s.isOpen()) {
                    MessageVo messageVo = new MessageVo();
                    Set<String> strings = routeTab.keySet();//在线用户名
                    messageVo.setBody(objectMapper.writeValueAsString(strings));//序列化成json存到 消息体
                    messageVo.setType(messageType);
                    s.getBasicRemote().sendText(objectMapper.writeValueAsString(messageVo));//给马老师发送在线用户
                }
            }
        }

    }

    //用户离开后10秒再检查，如果用户没有重连，则移除该用户，防止前端刷新时不断的刷新用户状态
    private void checkUserId(String userId) {
        CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(10000);
                if (!routeTab.get(userId).isOpen()) {
                    routeTab.remove(userId);
                    infoToTeacher(MessageType.LEAVE);
                    userIdTemp.remove(userId);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @OnClose
    public void onClose(@PathParam("userId") String userId) throws IOException {
        userIdTemp.add(userId);
        checkUserId(userId);
    }


    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println(message);
        MessageVo messageVo = objectMapper.readValue(message, MessageVo.class);//将字符串转成MessageVo
        messageVo.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        messageVo.setTime(new Date());
        for (String s : routeTab.keySet()) {
            Session session = routeTab.get(s);
            String s1 = objectMapper.writeValueAsString(messageVo);
            System.out.println(s1);
            session.getBasicRemote().sendText(s1);
        }
    }

    @OnError
    public void onError(Throwable error) {
        error.printStackTrace();
    }
}